﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using Kinlo.Drv.Drv.RJShortCirrcuitResult;
using Comm;
using Kinlo.Drv.Drv.RJShortCircuitEnum;
using Kinlo.Drv.DrvBases;

namespace Kinlo.Drv.Drv
{

    public class RJ6902B_ShortCircuitDrv : RJShortCircuitBase<Result<RJ6902B0X11>, Result<bool?>>
    {
        private readonly string IP;
        private readonly int Port;
        private readonly int TimeOut;
        private Socket socket;
        public bool IsOpen { get; private set; }
        public RJ6902B_ShortCircuitDrv(string ip, int port, int timeOut)
        {
            IP = ip;
            Port = port;
            TimeOut = timeOut;
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            {
                SendTimeout = TimeOut,
                ReceiveTimeout = TimeOut,
            };
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <returns>返回带访问标识的结果</returns>
        public override Result Connect()
        {
            try
            {
                if (IsOpen)
                {
                    _ = DisConnect();
                }
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(IP, Port);
                socket.SendTimeout = TimeOut;
                socket.ReceiveTimeout = TimeOut;
                IsOpen = true;
                return new Result { IsSuccess = true };
            }
            catch (Exception ex)
            {
                IsOpen = false;
                return new Result { ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <returns></returns>
        public override Result DisConnect()
        {
            try
            {
                if (socket.Connected)
                {
                    socket.Close();
                }
                IsOpen = false;
                return new Result { IsSuccess = true };
            }
            catch (Exception ex)
            {
                IsOpen = false;
                return new Result { ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        /// <summary>
        /// 发送命令至测试仪
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="localID">从机地址</param>
        /// <returns>返回带标识的对象</returns>
        private Result ShortCircuitCommand(CommandEnum command, byte localID)
        {
            try
            {
                List<byte> cmd = new byte[] { 0x7B, 0x00, 0x08, localID, CommandByte(command), (byte)command, 0x7D }.ToList();
                GetCheckNumber(ref cmd);
                _ = socket.Send(cmd.ToArray());
                byte[] data = new byte[2048];
                int count = socket.Receive(data);
                return GetResult(data.Take(count).ToArray());
            }
            catch (SocketException ex)
            {
                return new Result { Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        public override Result StartTest(byte localID)
        {
            return ShortCircuitCommand(CommandEnum.启动测试, localID);
        }

        public override Result<RJ6902B0X11> GetTestDataAndResult(byte localID)
        {
            try
            {
                Result result = ShortCircuitCommand(CommandEnum.查询测试判定数据和结果RJ6902R, localID);
                if (result.IsSuccess)
                {
                    byte[] data = result.Data.Skip(6).Take(17).ToArray();
                    Result<RJ6902B0X11> RjResult = new Result<RJ6902B0X11>
                    {
                        Data = result.Data,
                        Content = new RJ6902B0X11
                        {
                            Drop1 = int.Parse(data[0].ToString("X2") + data[1].ToString("X2")),
                            Drop2 = int.Parse(data[2].ToString("X2") + data[3].ToString("X2")),
                            VP_Voltage = Convert.ToInt32(data[4].ToString("X2") + data[5].ToString("X2"), 16),
                            UpperTime = Convert.ToInt32(data[6].ToString("X2") + data[7].ToString("X2"), 16),
                            OpenResult = GetResult(data[8]),
                            VoltageResult1 = GetResult(data[9]) ?? false,
                            VoltageResult2 = GetResult(data[10]) ?? false,
                            VP_Result = GetResult(data[11]) ?? false,
                            Drop1Result = GetResult(data[12]) ?? false,
                            Drop2Result = GetResult(data[13]) ?? false,
                            TLResult = GetResult(data[14]) ?? false,
                            THResult = GetResult(data[15]) ?? false,
                            Result = GetResult(data[16]) ?? false
                        },
                        ErroMessage = "",
                        IsSuccess = true,
                    };
                    return RjResult;
                }
                else
                {
                    return new Result<RJ6902B0X11> { Content = null, Data = result.Data, ErroMessage = result.ErroMessage, IsSuccess = false };
                }
            }
            catch (Exception ex)
            {
                return new Result<RJ6902B0X11> { Content = null, Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        public override Result<bool?> GetTestResult(byte localID)
        {
            try
            {
                Result result = ShortCircuitCommand(CommandEnum.查询测试结果RJ6902B, localID);
                if (result.IsSuccess)
                {
                    byte[] data = result.Data.Skip(6).Take(1).ToArray();
                    return new Result<bool?>
                    {
                        Data = result.Data,
                        Content = GetResult(data[0]),
                        ErroMessage = "",
                        IsSuccess = true
                    };
                }
                else
                {
                    return new Result<bool?> { Content = null, Data = result.Data, ErroMessage = result.ErroMessage, IsSuccess = false };
                }
            }
            catch (Exception ex)
            {
                return new Result<bool?> { Content = null, Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        /// <summary>
        /// 获取命令字节
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        private byte CommandByte(CommandEnum command)
        {
            switch (command)
            {
                case CommandEnum.启动测试:
                case CommandEnum.启动采集:
                case CommandEnum.保存采集波形:
                    return 0x0F;
                case CommandEnum.查询当前标准波形数据RJ6902B:
                case CommandEnum.查询测试波形数据RJ6902B:
                case CommandEnum.查询测试判定数据和结果RJ6902B:
                case CommandEnum.查询测试结果RJ6902B:
                case CommandEnum.查询标准波形信息RJ6902B:
                case CommandEnum.查询当前标准波形数据及参数RJ6902B:
                default:
                    return 0xF0;
            }
        }
    }
}
